/**
  * @file       list.h
  * @author     const_zpc (any question please send mail to const_zpc@163.com)
  * @brief      
  * @version    1.0
  * @date       2023-05-28
  * 
  * 
  * @par 使用方式: 
  * @code
  * 
  * @endcode
  * 
  * ********************************************************************************************************************
  */

/* Define to prevent recursive inclusion -----------------------------------------------------------------------------*/

#ifndef _COT_CONTAINER_LIST_H_
#define _COT_CONTAINER_LIST_H_

/* Includes ----------------------------------------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

#ifdef __cplusplus
 extern "C" {
#endif 

typedef struct stcotListItem
{
    struct stcotListItem *pPrev;
    struct stcotListItem *pNext; 
    void *pData;
} cotListItem_t;

typedef struct
{
    uint8_t nodeBufNum;
    cotListItem_t *pNodeBuf;
    cotListItem_t node; 
} cotList_t;

// 迭代器使用(自动指向下一个)
#define for_list_each(item, list) for (const cotListItem_t *item = cotList_Begin(&list); item != cotList_End(&list); item = cotList_Next(item))

// 反向迭代器使用(自动指向下一个)
#define for_list_each_r(item, list) for (const cotListItem_t *item = cotList_rBegin(&list); item != cotList_rEnd(&list); item = cotList_rNext(item))

// 迭代器使用(需要在循环内调用 item = cotList_Next(item) 指向下一个)
#define for_list(item, list) for (const cotListItem_t *item = cotList_Begin(&list); item != cotList_End(&list);)

// 反向迭代器使用(需要在循环内调用 item = cotList_rNext(item) 指向下一个)
#define for_list_r(item, list) for (const cotListItem_t *item = cotList_rBegin(&list); item != cotList_rEnd(&list);)

// 获取迭代器中的数据指针
#define item_ptr(type, item)    ((type *)item->pData)


extern void cotList_Init(cotList_t *pList, cotListItem_t *pNodeBuf,  uint8_t nodeBufNum);

extern const cotListItem_t *cotList_Begin(cotList_t *pList);
extern const cotListItem_t *cotList_End(cotList_t *pList);
extern const cotListItem_t *cotList_Next(const cotListItem_t *pListItem);
extern const cotListItem_t *cotList_rBegin(cotList_t *pList);
extern const cotListItem_t *cotList_rEnd(cotList_t *pList);
extern const cotListItem_t *cotList_rNext(const cotListItem_t *pListItem);

extern void *cotList_Front(cotList_t *pList);
extern void *cotList_Back(cotList_t *pList);

extern bool cotList_Empty(cotList_t *pList);
extern size_t cotList_Size(cotList_t *pList);

extern int cotList_Clear(cotList_t *pList);
extern int cotList_Insert(cotList_t *pList, const cotListItem_t *pListItem, const void *pdata);
extern int cotList_InsertItem(cotList_t *pList, const cotListItem_t *pListItem, cotListItem_t *pNewItem);
extern cotListItem_t * cotList_Erase(cotList_t *pList, const cotListItem_t *pListItem);
extern int cotList_Remove(cotList_t *pList, const void *pdata);
extern int cotList_RemoveIf(cotList_t *pList, bool (*pfnCondition)(const void *pData));
extern int cotList_PushFront(cotList_t *pList, const void *pdata);
extern int cotList_PopFront(cotList_t *pList);
extern int cotList_PushBack(cotList_t *pList, const void *pdata);
extern int cotList_PopBack(cotList_t *pList);
extern int cotList_Swap(cotList_t *pList1, cotList_t *pList2);

#ifdef __cplusplus
 }
#endif

#endif // !_COT_CONTAINER_LIST_H_
